// Deli.js
// Created By Philippe Gambling
// Handles deli.html forms and passing information to order.html

//
// Global Defines
//
// Using the non-blocking space character to clear error messages
// because I read online it was preferred to an empty string
var NBSP = String.fromCharCode(160);

//
// Helper Functions
//
// Set a status message on a specific element
function setMessage(message, className, targetId) {
  var element = document.getElementById(targetId);
  element.className = className;
  element.firstChild.nodeValue = message;
}
function clearMessage(targetId) {
  setMessage(NBSP, "success", targetId);
}
function errorMessage(message, targetId) {
  setMessage(message, "error", targetId);
}
// END Helpers

//
// Start Sandwich class definition
//

// Sandwich validates and stores the sandwich form inputs
function Sandwich(sandwichType) {
/*  Private Attributes*/
  var type = sandwichType;
  var quantity = 0;
  var meat = "";
  var spread = "";
  var cheese = "";
  var veggies = [];
  var price = "";
  
/*  Private Methods*/
  // Return true if the string is a positive number
  var isValidQuantity = function (input) {
    return /^\d+$/.test(input) && !/^0+$/.test(input);
  };

  var validateQuantity = function (input, targetId) {
    if(isValidQuantity(input) === true) {
      quantity = input;  
      clearMessage(targetId);
      return true;
    } else {
      errorMessage("Please enter a positive number.", targetId);
      return false;
    }
  };
  
/* Privilidged Methods  */
  // Make sure the quantity is positive whole number
  // and sets error messages as needed
  this.readInputs = function (formElements) {
    var retVal = true;

    for(var i=0; i<formElements.length; i++) {
      var element = formElements[i];
      var targetId = type+"-quantity-error";    
      
      switch(element.name) {
        case "quantity":
          retVal = validateQuantity(element.value, targetId) && retVal;
          break;
        case "meat":
          meat = element.value.toLowerCase();
          break;
        case "cheese":
          cheese = element.value.toLowerCase();
          break;
        case "spread":
          spread = element.value.toLowerCase();
          break;
        case "price":
          price = element.value;
          break;
        default:
          if(element.className=="veggies" && element.checked) { // Grab the selected veggies
            veggies.push(element.name); 
          } else { break; } // Ignore everything else
      }
    }
    
    return retVal;    
  };

  this.getPrice = function() { return (quantity*price).toFixed(2); };
  this.getQuantity = function() { return quantity; };
  
  this.toString = function() {
    var str = type+" with "+meat+","+cheese+","+spread;
    if(veggies.length > 0) { str += ","+veggies; }
    return str;
  };
}
// END Sandwich class definition

//
// Start CateringForm class definition
//
function CateringForm() {
/* Private Attributes */
  var date = "";
  var name = "";
  var street = "";
  var city = "";
  var state = "";
  var zip = "";

/* Private Methods */
  var validateDate = function (input) {
    var mmddyyyy = /\d{2}\/\d{2}\/\d{4}/;
    if(mmddyyyy.test(input)) {
      var splitDate = input.split('/');
      var month = splitDate[0];
      var day = splitDate[1];
      var year = splitDate[2];
      
      // Check for valid month
      if(month<1 || month>12) {
        setMessage("Month must be a number from 01 to 12.","error","date-error");
        return false;
      }

      // Check for valid day
      var leapYear = ((year%4 === 0) && (year%100 !== 0)) || (year%400 === 0);
      if((day<1) ||
         (day>31 && (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month ==12)) ||
         (day>30 && (month==4 || month==6 || month==9 || month==11)) ||
         (day>29 && month==2 && leapYear) ||
         (day>28 && month==2 && !leapYear)) {
        
        setMessage(day+" is not a valid day for that month.","error","date-error");
        return false;
      }
      
      // Make sure date isn't in the past
      var today = new Date();
      var inputDate = new Date(splitDate[2],splitDate[0]-1,splitDate[1]);
      if((inputDate < today) && (inputDate.toString().substring(0,15) != today.toString().substring(0,15))) {
        setMessage("Date is in the past.","error","date-error");
        return false;
      }
      setMessage(NBSP,"success","date-error");
      date = input;
      return true;
    } else {
      setMessage("Please enter the date in MM/DD/YYYY format.","error","date-error");
      return false;
    }
    
    return false;
  };

  var validateName = function (input, errorId) {
    if(/^([a-zA-Z].*[a-zA-Z]|[a-zA-Z])$/.test(input)) {
      setMessage(NBSP,"success",errorId);
      name += input+' ';
      return true;
    } else {
      setMessage("Name should start and end with a letter.","error",errorId);
      return false;
    }
  };

  var validateStreet = function (input) {
    if(/^\d+\s+[A-Za-z]+\s+[A-Za-z]+\.?\s*,?\s*[A-Za-z]*\s*#?\s*\d*/.test(input)) {
      setMessage(NBSP,"success","street-error");
      street = input;
      return true;
    }
    setMessage("Street should be number name street (optional: suffix, apartment number).","error","street-error");
    return false;
  };

  var validateCity = function (input) {
    if(/^([a-zA-Z].*[a-zA-Z]|[a-zA-Z])$/.test(input)) {
      setMessage(NBSP,"success","city-error");
      city = input;
      return true;
    }
    setMessage("City should start and end with a letter.","error","city-error");
    return false;
  };

  var validateState = function (input) {
    if(/TX/.test(input)) {
      setMessage(NBSP,"success","state-error");
      state = input;
      return true;
    }
    setMessage("State must be TX.","error","state-error");
    return false;
  };

  var validateZip = function (input) {
    if(/\d{5}/.test(input)) {
      setMessage(NBSP,"success","zip-error");
      zip = input;
      return true;
    }
    setMessage("Zip must be five digits.","error","zip-error");
    return false;
  };
  
/* Privilidged Methods */
  this.getDate = function() { return date; };
  this.getName = function() { return name; };
  this.getStreet = function() { return street; };
  this.getCity = function() { return city; };
  this.getState = function() { return state; };
  this.getZip = function() { return zip; };
  
  this.validateInput = function (formElements) {
    var retVal = true;
    
    for(var i=0; i<formElements.length; i++) {
      var element = formElements[i];
      
      switch(element.name) {
        case "date":
          retVal = validateDate(element.value) && retVal;
          break;
        case "first-name":
          retVal = validateName(element.value,"fname-error") && retVal;
          break;
        case "last-name":
          retVal = validateName(element.value,"lname-error") && retVal;
          break;
        case "street":
          retVal = validateStreet(element.value) && retVal;
          break;
        case "city":
          retVal = validateCity(element.value) && retVal;
          break;
        case "state":
          retVal = validateState(element.value) && retVal;
          break;
        case "zip":
          retVal = validateZip(element.value) && retVal;
          break;
        default: 
          break; // Just ignore everything else
      }
    }
    
    return retVal;
  };
}
// End CateringForm class definition

//
// Start Order class definition
//
// Order retains all the selected sandwiches, the catering information (if needed),
// and creates the order confirmation page.
function Order() {
/* Private Attributes */
  var delivery = false;
  var items =  [];
  var catering = new CateringForm();
  
/* Privilidged Methods */
  // Add a new sandwich to items array
  this.addSandwich = function(sandwich) {
    items.push(sandwich);
  };
  
  // Validates order information and displays order confirmation page
  this.finalizeOrder = function (formElements) {
    if(items.length === 0) {
      errorMessage("Add something to your order first.","submit-error");
      return false;
    }
    
    for(var i=0; i<formElements.length; i++) {
      var element = formElements[i];
      if(element.name == "deliver") { 
        delivery = element.checked; 
        break;
      }
    
    }
    // Validate name, address, and date information 
    catering = new CateringForm();
    if(delivery && catering.validateInput(formElements)===false) {
      return false;
    }  

    // Create order URL string
    var orderURL = "order.html?";

    if(delivery) {
      orderURL += "deliver&";
      orderURL += catering.getDate();
      orderURL += '&'+catering.getName();
      orderURL += '&'+catering.getStreet();
      orderURL += '&'+catering.getCity();
      orderURL += '&'+catering.getState();
      orderURL += '&'+catering.getZip()+'+';
    }
    
    for(i=0; i<items.length; i++) {
      orderURL += items[i].toString();
      orderURL += '&'+items[i].getQuantity();
      orderURL += '&'+items[i].getPrice()+'+';
    }
    
    orderURL = orderURL.substring(0,orderURL.length-1); // Remove the last '+'
    
    window.location = orderURL;
    
    return false; // Do not reload the page
  };
}
// End OrderObject definition

//
// Setup event handlers for all forms
//
var TheOrder = new Order();

// Event handler for poorboy and grill submit events
function sandwichHandler() {
  var type = this.className;
  var sandwich = new Sandwich(type);
  var targetId = type+"-submit-msg";
  
  if(sandwich.readInputs(this.elements)===true) {
    TheOrder.addSandwich(sandwich);
    setMessage("Successfully added selection to your order","success",targetId);
  } else {
    clearMessage(targetId);
  }
  
  return false;
}

// Event handler for complete order submission
function orderHandler() {
  return TheOrder.finalizeOrder(this.elements);
}

// Event handler to clear "successfully added" message
function clearAddMsg() {
  clearMessage(this.className+"-submit-msg");
}

// Initialize event handlers
function initEventHandlers() {
  document.getElementById("poorboy-form").onsubmit = sandwichHandler;
  document.getElementById("grill-form").onsubmit = sandwichHandler;
  document.getElementById("order-form").onsubmit = orderHandler;
  document.getElementById("poorboy-submit-button").onblur = clearAddMsg;
  document.getElementById("grill-submit-button").onblur = clearAddMsg;
}

window.onload = initEventHandlers;

